﻿//+-------------------------------------------------------------------------------------------------------------------------------------------------------
//
//Description:  StorageProfileViewModel
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using VmroleAuthor.Commands;
using VmroleAuthor.Models;

namespace VmroleAuthor.ViewModels
{
    public class StorageProfileViewModel : TreeViewItemViewModel, IDataErrorInfo, IProduceValidationResults
    {
        private readonly VmRoleResourceDefinitionViewModel vmRoleResourceDefinitionViewModel;
        private readonly VMStorageProfile storageProfile;

        private DiskParameterizableProperty osVirtualHardDiskImage;
        private readonly ObservableCollection<DataVirtualHardDiskViewModel> dataVirtualHardDiskViewModels;

        public static class PropertyNames
        {
            public const string Summary = "Summary";          
            public const string OSVirtualHardDiskImage = "OSVirtualHardDiskImage";
            public const string DataVirtualHardDisks = "DataVirtualHardDisks";    
        }

        public StorageProfileViewModel(
            VMStorageProfile storageProfile,
            VmRoleResourceDefinitionViewModel resourceDefinitionViewModel)
            : base(resourceDefinitionViewModel, true)
        {
            if (storageProfile == null)
            {
                storageProfile = new VMStorageProfile();
            }
            this.storageProfile = storageProfile;
            this.vmRoleResourceDefinitionViewModel = resourceDefinitionViewModel;
            this.dataVirtualHardDiskViewModels = new ObservableCollection<DataVirtualHardDiskViewModel>();
            if (this.storageProfile == null)
            {
                this.storageProfile = new VMStorageProfile();
            }
            if (this.storageProfile.DataVirtualHardDisks != null)
            {
                foreach (DataVirtualHardDisk dataVirtualHardDisk in this.storageProfile.DataVirtualHardDisks)
                {
                    this.dataVirtualHardDiskViewModels.Add(new DataVirtualHardDiskViewModel(dataVirtualHardDisk, this.vmRoleResourceDefinitionViewModel));                 
                }
            }

            this.AddDataVirtualHardDiskCommand = new RelayCommand(
             param => this.AddDataVirtualHardDisk(),
             param => this.CanAddDataVirtualHardDisk());

            this.DeleteDataVirtualHardDiskCommand = new RelayCommand(
                param => this.DeleteDataVirtualHardDisk((DataVirtualHardDiskViewModel)param),
                param => this.CanDeleteDataVirtualHardDisk((DataVirtualHardDiskViewModel)param));    

            this.ValidationResults = new ObservableCollection<CloudServiceModelValidationResult>();        
 
            if (this.vmRoleResourceDefinitionViewModel.IsNewResdefCreatedByTheTool)
            {
                this.OSVirtualHardDiskImage.PropertyValue = ParametersViewModel.AutoGenerateMoniker;
            }
        }

        public string Summary
        {
            get
            {                
                return "Storage Profile";
            }
        }

        public DiskParameterizableProperty OSVirtualHardDiskImage
        {
            get
            {
                if (this.osVirtualHardDiskImage == null)
                {
                    Func<string> paramValueGetter = () => this.storageProfile.OSVirtualHardDiskImage;
                    Action<string> paramValueSetter = delegate(string value) { this.storageProfile.OSVirtualHardDiskImage = value; };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.OSVirtualHardDiskImage;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        IsRecommendedToBeParameterized = true,
                        ViewDefParameterType = ViewDefParameterType.OSVirtualHardDisk,                      
                        DefaultEnglishLabelText = "Operating system disk"
                    };

                    this.osVirtualHardDiskImage = new DiskParameterizableProperty(
                        PropertyNames.OSVirtualHardDiskImage,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Operating system disk",
                        this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                        true,
                        viewDefParamInfo);
                }
                return this.osVirtualHardDiskImage;
            }
        }

        public ObservableCollection<DataVirtualHardDiskViewModel> DataVirtualHardDisks
        {
            get { return this.dataVirtualHardDiskViewModels; }
        }

        public ICommand AddDataVirtualHardDiskCommand
        {
            get;
            private set;
        }

        public ICommand DeleteDataVirtualHardDiskCommand
        {
            get;
            private set;
        }

        public bool CanAddDataVirtualHardDisk()
        {
            return true;
        }

        public void AddDataVirtualHardDisk()
        {
            DataVirtualHardDisk env = new DataVirtualHardDisk();
            if (this.storageProfile.DataVirtualHardDisks == null)
            {
                this.storageProfile.DataVirtualHardDisks = new List<DataVirtualHardDisk>();
            }
            this.storageProfile.DataVirtualHardDisks.Add(env);
            var viewModel = new DataVirtualHardDiskViewModel(env, this.vmRoleResourceDefinitionViewModel);
            this.dataVirtualHardDiskViewModels.Add(viewModel);
        }

        public bool CanDeleteDataVirtualHardDisk(DataVirtualHardDiskViewModel dataVirtualHardDiskViewModel)
        {
            return true;
        }

        public void DeleteDataVirtualHardDisk(DataVirtualHardDiskViewModel dataVirtualHardDiskViewModel)
        {
            if (dataVirtualHardDiskViewModel != null)
            {
                dataVirtualHardDiskViewModel.Cleanup();
                if (this.storageProfile.DataVirtualHardDisks != null)              
                {
                    this.storageProfile.DataVirtualHardDisks.Remove(dataVirtualHardDiskViewModel.DataVirtualHardDisk);
                }
                this.dataVirtualHardDiskViewModels.Remove(dataVirtualHardDiskViewModel);
            }
        }

        
        public string this[string propertyName]
        {
            get
            {               
                return null;
            }
        }

        public string Error { get; set; }

        public ObservableCollection<CloudServiceModelValidationResult> ValidationResults { get; private set; }

        public void UpdateValidationResults()
        {
            this.IsExpanded = true;
            ModelValidationResultsHelper.UpdateValidationResults(this, typeof(PropertyNames));
            //Add any other cross-field validations error            
        }     
    }
}
